<template>
  <div class="contBody">
    <h2 class="title">热区图表</h2>
    <div id="mapCharts" class="map__x"></div>
    <div class="btnGroup">
      <el-button type="primary" @click="addChartsHnadle('Column2D')">
        加载柱状图
      </el-button>
      <el-button type="primary" @click="addChartsHnadle('Line')">
        加载折线图
      </el-button>
      <el-button type="primary" @click="addChartsHnadle('Pie2D')">
        加载饼图
      </el-button>
    </div>
  </div>
</template>

<script>
import { Map, View, Feature, Overlay } from "ol"; // 地图实例方法、视图方法
import Tile from "ol/layer/Tile"; // 瓦片渲染方法
import Vector from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Style, Fill, Stroke, Circle } from "ol/style";
import Polygon from "ol/geom/Polygon";
// todo EPSG:3857 转 EPSG:4326
// import { transform } from "ol/proj";
import { fromLonLat } from "ol/proj";
import XYZ from "ol/source/XYZ";
import "ol/ol.css"; // 地图样式

import { data } from "@/assets/json/data.js";

import { getCurrentInstance } from "vue";

export default {
  name: "MapPage",
  data() {
    return {
      map: null,
    };
  },
  mounted() {
    // 基于准备好的dom，初始化echarts图表
    const { proxy } = getCurrentInstance();
    this.proxy = proxy;
    this.initMap();
  },
  methods: {
    initMap() {
      // 地图实例
      this.map = new Map({
        target: "mapCharts", // 对应页面里 id 为 map 的元素
        layers: [
          // 图层
          new Tile({
            source: new XYZ({
              url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7", // 新高德地图
            }),
            visible: true,
          }),
        ],
        view: new View({
          // 地图视图
          // projection: "EPSG:4326", // 坐标系，有EPSG:4326和EPSG:3857
          // center: [100.864943, 24.041115], // 云南坐标
          // minZoom: 5, // 地图缩放最小级别
          // zoom: 6, // 地图缩放级别（打开页面时默认级别）

          // EPSG:3857
          center: fromLonLat([114, 32]),
          zoom: 5,
        }),
      });

      //绘制热区的样式
      const flashStyle = new Style({
        fill: new Fill({
          color: "rgba(0, 148, 255,0.2)",
        }),
        stroke: new Stroke({
          color: "#cc3300",
          width: 3,
        }),
        image: new Circle({
          radius: 7,
          fill: new Fill({
            color: "#cc3300",
          }),
        }),
      });

      //矢量数据源
      this.vectSource = new VectorSource({});
      //矢量图层
      const vectLayer = new Vector({
        source: this.vectSource,
        style: flashStyle,
        opacity: 1,
      });
      this.map.addLayer(vectLayer);
    },

    addChartsHnadle(type) {
      const overLayers = this.map.getOverlays();
      overLayers.clear(); //移除所有Overlays图层

      this.selectRegData(type);
    },

    selectRegData(type) {
      this.vectSource.clear();
      const resultData = data; //查询结果json数组
      resultData.forEach((item) => {
        //解析结果集中的几何字符串，并转换为多边形的几何数组
        const polyCoords = item.Geometry.split(";");
        const coordinates = new Array();
        coordinates[0] = new Array();
        for (let i = 0; i < polyCoords.length; i++) {
          coordinates[0][i] = polyCoords[i].split(",");
          // todo EPSG:3857 转 EPSG:4326
          // coordinates[0][i] = transform(
          //   polyCoords[i].split(","),
          //   "EPSG:3857",
          //   "EPSG:4326"
          // );
        }
        //创建一个新的要素，并添加到数据源中
        const feature = new Feature({
          geometry: new Polygon(coordinates),
          name: item.name,
          id: item.ID,
        });
        this.vectSource.addFeature(feature);

        //得到feature的外包矩形中心点
        const fGeometry = feature.getGeometry();
        const fExtent = fGeometry.getExtent();
        const centerX = fExtent[0] + (fExtent[2] - fExtent[0]) / 2;
        const centerY = fExtent[1] + (fExtent[3] - fExtent[1]) / 2;
        const center = [centerX, centerY]; //外包矩形中心点

        //为每个区域要素加载统计图
        this.addCharts(item, center, type);
      });
    },

    async addCharts(itemData, coordinate, type) {
      const mapContainer = document.getElementById("mapCharts"); //地图容器对象

      //新增div元素，用来承载统计图
      let elementDiv = document.createElement("div");
      elementDiv.id = "chart" + itemData.ID;
      elementDiv.className = "linechart";
      elementDiv.style.width = "200px";
      elementDiv.style.height = "200px";

      mapContainer.appendChild(elementDiv); // 为mapContainer添加div子节点

      console.log(elementDiv);
      //创建一个Overlay控件
      const newOverLayer = new Overlay({
        element: elementDiv,
        autoPan: true,
        positioning: "bottom-center",
      });
      newOverLayer.setPosition(coordinate);
      this.map.addOverlay(newOverLayer);

      this.chart = this.proxy.$echarts.init(elementDiv);
      // 根据不同图表类型创建相应图表
      this.chart.setOption(this.initChartOption(itemData, type));
    },

    initChartOption(itemData, chartType) {
      let option = {};
      switch (chartType) {
        case "Column2D":
          option = {
            //设置标题
            title: {
              text: itemData.name + "近三年GDP",
              x: "left",
              y: "bottom",
            },
            //设置提示
            tooltip: {
              show: true,
            },
            backgroundColor: "rgba(128, 128, 128,0.5)",
            //设置图例
            legend: {
              data: ["GDP(万亿)"],
            },
            //X轴信息
            xAxis: [
              {
                type: "category", //默认为类目
                data: ["2015", "2016", "2017"],
              },
            ],
            //Y轴信息
            yAxis: [
              {
                type: "value", //默认为值类型
              },
            ],
            //显示的值
            series: [
              {
                name: "GDP(万亿)", //图表类型
                type: "bar", //图表类型
                data: [
                  +itemData.GDP_2015 / 10000,
                  +itemData.GDP_2016 / 10000,
                  +itemData.GDP_2017 / 10000,
                ], //图表数据
              },
            ],
          };
          break;
        case "Line":
          option = {
            //设置标题
            title: {
              text: itemData.name + "近三年GDP",
              x: "left",
              y: "bottom",
            },
            tooltip: {
              show: true,
            },
            backgroundColor: "rgba(128, 128, 128,0.5)",
            legend: {
              data: ["GDP(万亿)"],
            },
            xAxis: {
              type: "category",
              data: ["2015", "2016", "2017"],
            },
            yAxis: {
              type: "value",
            },
            series: [
              {
                name: "GDP(万亿)",
                data: [
                  +itemData.GDP_2015 / 10000,
                  +itemData.GDP_2016 / 10000,
                  +itemData.GDP_2017 / 10000,
                ],
                type: "line",
              },
            ],
          };
          break;
        case "Pie2D":
          option = {
            title: {
              text: itemData.name + "GDP(万亿)",
              x: "right",
              y: "top",
            },
            tooltip: {
              trigger: "item",
              formatter: "{a} <br/>{b} : {c} ({d}%)",
            },
            legend: {
              orient: "vertical",
              left: "left",
              data: ["2015", "2016", "2017"],
            },
            series: [
              {
                name: "GDP",
                type: "pie",
                radius: "55%",
                center: ["50%", "60%"],
                data: [
                  { value: +itemData.GDP_2015 / 10000, name: "2015" },
                  { value: +itemData.GDP_2016 / 10000, name: "2016" },
                  { value: +itemData.GDP_2017 / 10000, name: "2017" },
                ],
                itemStyle: {
                  emphasis: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: "rgba(0, 0, 0, 0.5)",
                  },
                },
              },
            ],
          };
          break;
        default:
          break;
      }
      return option;
    },
  },
};
</script>

<style lang="css" scoped>
.contBody .title {
  padding: 0 0 24px;
}
.map__x {
  width: 100%;
  height: 600px;
  border: 1px solid #eee;

  position: relative;
}
.btnGroup {
  text-align: left;
}
</style>
